//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using Microsoft.Research.ScientificWorkflow.UIDesigner.WpfComposite;
using Microsoft.Practices.Unity;
using Microsoft.Research.ScientificWorkflow.ManagementStudioControls.Common;
using System.Windows.Input;

namespace Microsoft.Research.ScientificWorkflow.ManagementStudioControls.RegistryManagerModule
{
    public class RegistryManagerLeftPanePresenter : ILeftPaneControl
    {
        /// <summary>
        /// The unity container instance.
        /// </summary>
        IUnityContainer container;

        /// <summary>
        /// The presenters corresponding to the items in the left pane.
        /// </summary>
        private Dictionary<string, IRegistryManagerLeftPaneItemPresenter> registryManagerListPresenters = new Dictionary<string, IRegistryManagerLeftPaneItemPresenter>();

        /// <summary>
        /// The previously selected presenter.
        /// </summary>
        private IRegistryManagerLeftPaneItemPresenter previouslySelectedLeftPanePresenter;

        /// <summary>
        /// The previous center pane presenter.
        /// </summary>
        private IRegistryManagerCenterPanePresenter previouslySelectedCenterPanePresenter;

        /// <summary>
        /// Initializes a new instance of the <see cref="RegistryManagerLeftPanePresenter"/> class.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="view">The view.</param>
        /// <param name="mainContent">Content of the main.</param>
        public RegistryManagerLeftPanePresenter(IUnityContainer container, RegistryManagerLeftPaneView view, RegistryManagerContentView mainContent)
        {
            this.ObjectName = "Registry Manager";
            this.container = container;
            this.LeftPaneContent = view;
            this.MainContent = mainContent;
            view.DataContext = this;

            this.Items = new ObservableCollection<RegistryManagerLeftPaneItemModel>();
            this.ItemExpanded = new DelegateCommand<Expander>(this.ItemExpandedExecute);
            this.ItemSelected = new DelegateCommand<object[]>(this.ItemSelectedExecute);
            this.ItemRefreshed = new DelegateCommand<Expander>(this.ItemRefreshExecute);
        }

        #region ILeftPaneControl Members

        /// <summary>
        /// 
        /// </summary>
        public UIElement LeftPaneContent { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public UIElement MainContent { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public ToggleButton Selector { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string ObjectName { get; set; }

        #endregion

        /// <summary>
        /// Gets or sets the items.
        /// </summary>
        /// <value>The items.</value>
        public ObservableCollection<RegistryManagerLeftPaneItemModel> Items { get; private set; }

        /// <summary>
        /// Gets or sets the item expanded.
        /// </summary>
        /// <value>The item expanded.</value>
        public DelegateCommand<Expander> ItemExpanded { get; private set; }

        /// <summary>
        /// Gets or sets the item selected.
        /// </summary>
        /// <value>The item selected.</value>
        public DelegateCommand<object[]> ItemSelected { get; private set; }

        /// <summary>
        /// Gets or sets the item Refresh Command.
        /// </summary>
        /// <value>The item selected.</value>
        public DelegateCommand<Expander> ItemRefreshed { get; private set; }

        /// <summary>
        /// Adds the specified left pane item.
        /// </summary>
        /// <param name="leftPaneItem">The left pane item.</param>
        /// <param name="presenter">The presenter.</param>
        public void Add(RegistryManagerLeftPaneItemModel leftPaneItem, IRegistryManagerLeftPaneItemPresenter presenter)
        {
            this.registryManagerListPresenters.Add(leftPaneItem.RootKey, presenter);
            presenter.LeftPanePresenter = this;
            this.Items.Add(leftPaneItem);
        }

        /// <summary>
        /// Saves the changes on the view.
        /// </summary>
        /// <returns>
        /// Value indicating success or failure of the save.
        /// </returns>
        public SaveStateHandler SaveChanges()
        {
            SaveStateHandler saveState = new SaveStateHandler(SaveStatus.Valid);
            if (this.previouslySelectedCenterPanePresenter != null)
            {
                saveState = this.previouslySelectedCenterPanePresenter.SaveChanges();
            }

            return saveState;
        }

        /// <summary>
        /// Executes expansion call of the expander.
        /// </summary>
        /// <param name="expander">The expander.</param>
        private void ItemExpandedExecute(Expander expander)
        {
            RegistryManagerLeftPaneItemModel selectedModel = expander.DataContext as RegistryManagerLeftPaneItemModel;
            if (!selectedModel.IsInitialized)
            {
                IRegistryManagerLeftPaneItemPresenter requiredPresenter = this.registryManagerListPresenters[selectedModel.RootKey];
                if (requiredPresenter != null)
                {
                    expander.Content = requiredPresenter.LeftPaneView;
                    requiredPresenter.Initialize();
                    selectedModel.IsInitialized = true;
                }
            }
        }


        /// <summary>
        /// Executes expansion call of the expander.
        /// </summary>
        /// <param name="expander">The expander.</param>
        private void ItemRefreshExecute(Expander expander)
        {
            try
            {
                Mouse.OverrideCursor = Cursors.Wait;
                RegistryManagerLeftPaneItemModel selectedModel = expander.DataContext as RegistryManagerLeftPaneItemModel;

                IRegistryManagerLeftPaneItemPresenter requiredPresenter = this.registryManagerListPresenters[selectedModel.RootKey];
                if (requiredPresenter != null)
                {
                    SaveStateHandler handler = requiredPresenter.LeftPanePresenter.SaveChanges();
                    if (handler.SaveOptionSelected == SaveStatus.Valid)
                    {
                        requiredPresenter.Refresh(this.previouslySelectedCenterPanePresenter.SelectedModel);
                    }
                }
            }
            finally
            {
                Mouse.OverrideCursor = Cursors.Arrow;
            }
        }


        
        /// <summary>
        /// Selects the item.
        /// </summary>
        /// <param name="presenter">The presenter.</param>
        private void ItemSelectedExecute(object[] presenters)
        {
            ////Previous presenter and current presenter
            const int MINIMUM_PRESENTER_AVAILABLE = 2;
            
            if (presenters.Length > MINIMUM_PRESENTER_AVAILABLE)
            {
                IRegistryManagerCenterPanePresenter centerPanePresenter = presenters[0] as IRegistryManagerCenterPanePresenter;
                IRegistryManagerLeftPaneItemPresenter leftPanePresenter = presenters[1] as IRegistryManagerLeftPaneItemPresenter;
                SaveStateHandler userOption = presenters[2] as SaveStateHandler;
                if (centerPanePresenter != null && leftPanePresenter != null)
                {
                    if (this.previouslySelectedCenterPanePresenter != null)
                    {
                        if (SaveStatus.Invalid == this.previouslySelectedCenterPanePresenter.SaveChanges().SaveOptionSelected)
                        {
                            userOption.SaveOptionSelected = SaveStatus.Invalid;
                            return;
                        }

                        if (this.previouslySelectedLeftPanePresenter == leftPanePresenter
                            && this.previouslySelectedCenterPanePresenter == centerPanePresenter)
                        {
                            return;
                        }

                        
                        this.previouslySelectedLeftPanePresenter.IsSelected = false;
                    }

                    (this.MainContent as RegistryManagerContentView).AddItemsView(centerPanePresenter.ContentView);
                    this.previouslySelectedLeftPanePresenter = leftPanePresenter;
                    this.previouslySelectedCenterPanePresenter = centerPanePresenter;
                    this.previouslySelectedLeftPanePresenter.IsSelected = true;
                }
            }
        }
    }
}
